package com.example.foo.member.service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.core.PageResult;
import com.example.core.Pageable;
import com.example.foo.member.model.Withdraw;
import com.example.foo.member.query.WithdrawQuery;
import com.example.foo.member.WithdrawException;
import com.example.foo.member.dao.WithdrawDao;

@org.springframework.stereotype.Service
public class WithdrawService {

	private final WithdrawDao withdrawDao;

	public WithdrawService(WithdrawDao withdrawDao) {
		this.withdrawDao = withdrawDao;
	}

	// ========== Withdraw ==========

	public PageResult<Withdraw> findWithdraws(WithdrawQuery withdrawQuery, Pageable pageable) {
		return withdrawDao.findWithdraws(withdrawQuery, pageable);
	}

	public List<Withdraw> findWithdrawsByIds(List<Long> ids) {
		return withdrawDao.selectBatchIds(ids);
	}

	public Withdraw findWithdrawById(Long id) {
		return withdrawDao.selectById(id);
	}

	public boolean findWithdrawCountExistByUserId(Long userId) {
		return withdrawDao.selectCount(new QueryWrapper<Withdraw>()
				.eq("user_id", userId)
				) > 0;
	}

	public Withdraw findWithdrawLatestByUserId(Long userId) {
		WithdrawQuery withdrawQuery = new WithdrawQuery();
		withdrawQuery.setUserId(userId);
		Pageable pageable = new Pageable(1, 1);
		pageable.setSort("created_at DESC, id DESC");
		PageResult<Withdraw> pageResult = withdrawDao.findWithdraws(withdrawQuery, pageable);
		if (pageResult.getRows().isEmpty()) {
			return null;
		}
		return pageResult.getRows().get(0);
	}

	public void createWithdrawPending(String bankName, String bankBranchName, String cardHolder, String cardNumber, BigDecimal money, BigDecimal serviceFee, Long userId) {
		String withdrawNo = "1" + System.currentTimeMillis() + StringUtils.leftPad(userId % 9999 + "", 4, '0');//TODO

		Withdraw withdraw = new Withdraw();
		withdraw.setState(Withdraw.State.pending);
		withdraw.setWithdrawNo(withdrawNo);
		withdraw.setBankName(bankName);
		withdraw.setBankBranchName(bankBranchName);
		withdraw.setCardHolder(cardHolder);
		withdraw.setCardNumber(cardNumber);
		withdraw.setMoney(money);
		withdraw.setServiceFee(serviceFee);
		withdraw.setMemo("");
		withdraw.setOuterOrderNo("");
		withdraw.setUserId(userId);
		withdraw.setCreatedAt(LocalDateTime.now());
		withdrawDao.insert(withdraw);
	}

	public void updateWithdrawOuterOrderNo(Long id, String memo, String outerOrderNo) {
		Withdraw withdraw = new Withdraw();
		withdraw.setId(id);
		withdraw.setMemo(memo);
		withdraw.setOuterOrderNo(outerOrderNo);
		withdraw.setUpdatedAt(LocalDateTime.now());
		withdrawDao.updateById(withdraw);
	}

	public void updateWithdrawSuccess(Long id, String memo) {
		Withdraw withdraw = withdrawDao.selectById(id);
		if (withdraw.getState() != Withdraw.State.pending) {
			throw new WithdrawException(String.format("状态错误: %s", withdraw.getState().text));
		}

		withdraw.setState(Withdraw.State.success);
		withdraw.setMemo(memo);
		withdraw.setUpdatedAt(LocalDateTime.now());
		withdrawDao.updateById(withdraw);
	}

	public void updateWithdrawFailure(Long id, String memo) {
		Withdraw withdraw = withdrawDao.selectById(id);
		if (withdraw.getState() != Withdraw.State.pending) {
			throw new WithdrawException(String.format("状态错误: %s", withdraw.getState().text));
		}

		withdraw.setState(Withdraw.State.failure);
		withdraw.setMemo(memo);
		withdraw.setUpdatedAt(LocalDateTime.now());
		withdrawDao.updateById(withdraw);
	}

	public void updateWithdrawFinish(Long id, String memo) {
		Withdraw withdraw = withdrawDao.selectById(id);
		if (withdraw.getState() != Withdraw.State.success) {
			throw new WithdrawException(String.format("状态错误: %s", withdraw.getState().text));
		}

		withdraw.setState(Withdraw.State.finish);
		withdraw.setMemo(memo);
		withdraw.setUpdatedAt(LocalDateTime.now());
		withdrawDao.updateById(withdraw);
	}

}
